<?php
/**
 * XmuSlh, web platform of Student Association Federation of Xiamen University
 * 
 * Rewritting one or some pages of StatusNet. 
 * To get the original version, please visit <http://status.net/>.
 * 
 * StatusNet, the distributed open-source microblogging tool
 * 
 * LICENCE: This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * The Association class for table 'association'.
 * 
 * @author		ytukie <ytukie@gmail.com>
 * @version		0.44
 * 
 * 0.2)  Adds the column 'pinyin',
 * 		 Adds some functional methods.
 * 0.21) Adds the 'getIdsByList' function.
 * 0.3)  Adds the self identity column 'id'. (primary auto_increment).
 * 0.4)  Adds the 'category' column to distinguish in antoher way.
 * 		 Adds the 'validateCategory' function.
 * 0.41) Adds the column 'weibo_id'.
 * 0.42) Changes the column 'description' to 'rendered'.
 * 0.43) Adds the 'Association_Mark' feature.
 * 0.44) Sets the original password the random one!
 */

// XmuSlh only.
if ( !defined('XMUSLH')) { exit(1); }

// Requirements.
require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
require_once INSTALLDIR . '/classes/User.php';
require_once INSTALLDIR . '/classes/Association.php';
require_once INSTALLDIR . '/classes/Association_Mark.php';

require_once INSTALLDIR . '/lib/slh_util.php';
require_once INSTALLDIR . '/lib/slh_cache.php';
require_once INSTALLDIR . '/lib/slh_arraywrapper.php';

// Definitoins.
define('ASSOCIATION_CATEGORY_NULL',				0);		// 未分类
define('ASSOCIATION_CATEGORY_CULTURE',			1);		// 文化艺术
define('ASSOCIATION_CATEGORY_SCIENCE',			2);		// 科技学术
define('ASSOCIATION_CATEGORY_SPORTS',			3);		// 体育健身
define('ASSOCIATION_CATEGORY_PRACTICE',			4);		// 社会实践


class Association extends Memcached_DataObject
{
	public $__table = 'association';		// table name
	public $id;								// int(11)  primary_key not_null foreign_key
	public $user_id;						// int(11)  foreign_key unique not_null
	public $cnname;							// varchar(255)  unique not_null
	public $enname;							// varchar(255)
	public $category;						// tinyint(4)  emun
	public $pinyin;							// varchar(255)
	public $rendered;						// text
	public $weibo_id;						// int(11)
	public $association_rights;				// int(9)  unsigned not_null
	public $modified;						// timestamp()  not_null
	
	static $categories = array('文化艺术类' => ASSOCIATION_CATEGORY_CULTURE,
							   '科技学术类' => ASSOCIATION_CATEGORY_PRACTICE,
							   '体育健身类' => ASSOCIATION_CATEGORY_SCIENCE,
							   '社会实践类' => ASSOCIATION_CATEGORY_SPORTS);

	static $categorynames = array(ASSOCIATION_CATEGORY_CULTURE => '文化艺术类',
								  ASSOCIATION_CATEGORY_PRACTICE => '科技学术类',
								  ASSOCIATION_CATEGORY_SCIENCE => '体育健身类',
								  ASSOCIATION_CATEGORY_SPORTS => '社会实践类',
								  ASSOCIATION_CATEGORY_NULL => '未分类');
	
	// Static get
	function staticGet($key, $value = null)
	{
		return Memcached_DataObject::staticGet('Association', $key, $value); 
	}
	
	/**
	 * Get the user object.
	 * 'association'.'user_id' => 'user'.'id'
	 */
	function getUser()
	{
		return User::staticGet('id', $this->user_id);
	}
	
	/**
	 * Get the catagoriy name.
	 */
	function getCatagoryName()
	{
		return self::$categorynames[$this->category];
	}
	
	/**
	 * Validate the value of the category if is in the emun array.
	 */
	static function validateCategory($category)
	{
		if (in_array($category, Association::$categories)) {
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * Adds a new association account in the table 'association'.
	 * 
	 * Befaore doing this, account must be inserted correctly in the
	 * table 'user'. So the 'user_id' should be correct.
	 * FIXME: Use the transaction.
	 * 
	 * @return The Association id.
	 */
	static function add($fields)
	{
		// Magically put fields into current scope.
		extract($fields);
		
		$user = new User();
		$user->status = USER_STATUS_VERIFIED;
		$user->username = $username;
		$user->password = md5(time());
		$user->type = USER_TYPE_ASSOCIATION;
		$user->created = slh_sql_now();
		
		// BEGIN
		$user->query('BEGIN');
		
		$user_id = $user->insert();
		if (empty($user_id)) {
			slh_log_db_error($user, 'INSERT', __FILE__);
			return false;
		}
		$user->user_id = $user_id;
		
		$association = new Association();
		$association->user_id = $user_id;
		$association->cnname = $cnname;
		$association->enname = $enname;
		$association->category = $category;
		$association->pinyin = strtolower($pinyin);
		$association->rendered = $rendered;
		$association->weibo_id = $weibo_id;
		$association->association_rights = $association_rights;
		
		$result = $association->insert();
		if (empty($result)) {
			slh_log_db_error($association, 'INSERT', __FILE__);
			return false;
		}
		
		$association_mark = new Association_Mark();
		$association_mark->user_id = $user_id;
		$result = $association_mark->insert();
		if (empty($result)) {
			slh_log_db_error($association_mark, 'INSERT', __FILE__);
			return false;
		}
		
		// COMMIT
		$user->query('COMMIT');
		
		return $user_id;
	}
	
	/**
	 * Get the ids as a list. Use offset and limit to control
	 * the pagination.
	 */
	static function getUseridsByList($offset = 0,
								 	 $limit = 0)
	{
		$association = new Association();
		
		$association->selectAdd();
		$association->selectAdd('user_id');
		
		$association->whereAdd('user_id in (SELECT `id` FROM `user`)');
		
		// $association->orderBy('user_id DESC');
		
		if ( !is_null($offset)) {
			$association->limit($offset, $limit);
		}
		
		$userids = array();
		if ($association->find()) {
			while ($association->fetch()) {
				$userids[] = $association->user_id;
			}
		}
		
		$association->free();
		$association = NULL;
		
		return $userids;
	}
	
	/**
	 * Get the special ids of the association users.
	 * 
	 * Usually the list with pagination.
	 */
	function getAssociationsByUserids($userids)
	{
		$cache = Cache::instance();
		
		if ( !empty($cache)) {
			$associations = array();
			foreach ($userids as $userid) {
				$a = Association::staticGet('user_id', $userid);
				if ( !empty($a)) {
					$associations[] = $a;
				}
			}
			
			return new ArrayWrapper($associations);
		} else {
			// Miss the cache.
			$associations = new Association();
			if (empty($userids)) {
				return $associations;
			}
			
			$associations->whereAdd('user_id in (' . implode(', ', $userids) . ')');
			$associations->find();
			
			$temp = array();
			while ($associations->fetch()) {
				$temp[$associations->id] = clone($associations);
			}
			
			$wrapped = array();
			
			foreach($userids as $userid) {
				if (array_key_exists($userid, $temp)) {
					$wrapped[] = $temp[$userid];
				}
			}
			
			return new ArrayWrapper($wrapped);
		}
	}
}
?>